<template>
  <!-- <div :class="{'data-visualization-container': true, fold: !isShowVisualization}"> -->
  <div class="data-visualization-container">
    <div class="section-content">
      <favorite-panel :pipeline-id="pipelineId" />
      <!-- <visualization-edit-modal :is-modal-visible="isModalShow" @ok="onConfirmEdit" @cancel="onCancel"/> -->
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator'
import Chart from '@/components/chart/chart.vue'
import DataStore from '@/store/modules/dataview'
import { isEqual, merge } from 'lodash'
import VisualizationEditModal from '@/components/studio/data/node-edit-panel/VisualizationEditModal.vue'
import RightDrawer from '@/components/studio/data/drawer/RightDrawer.vue'
import {
  getAndDealWidgetData,
  removeNullEntries,
} from '@/util/recommend-visualization'
import {
  widgetQueryByTaskId,
  updateWidget,
  deleteWidget,
  saveWidget,
  getGlobalWidgets,
} from '@/api/widget'
import { Widget, WidgetData } from '@/util/chart-widget'
import FavoritePanel from '@/views/studio/favorite-panel.vue'

interface ResponseData {
  code: number
  success: boolean
  result: any
}

@Component({
  components: {
    Chart,
    VisualizationEditModal,
    RightDrawer,
    FavoritePanel,
  },
})
export default class DataVisualization extends Vue {
  private activeKey2 = ['1']
  private isShowVisualization: boolean = false
  private displayMode: 'fold' | 'unfold' = 'unfold'
  private activeKey: 'visualization' | 'recommendation' = 'visualization'
  private tabData: any = [
    {
      name: '可视化收藏',
      key: 'visualization',
    },
    // {
    //   name: '透视推荐',
    //   key: 'recommendation'
    // }
  ]

  private miscChartOptions = {
    size: [190, 100],
    labelIsShow: false,
    legendIsShow: false,
    padding: [10, 20, 10, 10],
    titleIsShow: false,
    yAxisTitleFontSize: 10,
    xAxisTitleFontSize: 10,
    axisTitleIsShow: true,
    xAxisRenderMode: 'simple',
    yAxisRenderMode: 'simple',
    titleFontColor: '#373B52',
    xAxisTickIsShow: false,
    yAxisTickIsShow: false,
    xAxisFontColor: '#373B52',
    yAxisFontColor: '#373B52',
    xAxisLineColor: '#e9e9e9',
    yAxisLineColor: '#e9e9e9',
    axisLineColor: '#e9e9e9',
    axisTickColor: '#e9e9e9',
  }

  private allWidgets: any
  private nodeWidgets: Widget[] = []
  private isNodeWidgetsLoading: boolean = false
  private editingWidget: Widget | null = null
  // pipelineId 沿用版本1
  @Prop({ type: Number, default: 0 })
  pipelineId!: number

  /**
   * pipeline 传值监听, pipeline 传入 跟新 pipeline
   */
  @Watch('pipelineId')
  public changePipelineId() {
    // this.updatePipeline()
  }

  public beforeMount() {
    // console.log('bbefore mounted')
    // this.updatePipeline()
  }

  mounted() {
    localStorage.setItem('projectId', `${(this.$route.params as any).id || ''}`)
    DataStore.setNodeEditPanelIsShowVisualization(this.isShowVisualization)
  }
  /**
   * 全局 更新 画布
   */
  public updatePipeline() {
    this.getGlobalWidgets()
  }

  favoriteClose() {
    console.log('1')
  }

  private get selectNode() {
    return DataStore.selectNode
  }

  public get isModalShow() {
    return DataStore.getVisualWindowShow
  }

  public get savingWidgetConfig() {
    return DataStore.savingWidgetConfig
  }

  toggleTabKey(tab: any) {
    this.activeKey = tab.key
  }

  toggleDisplayMode() {
    this.isShowVisualization = !this.isShowVisualization
    DataStore.setNodeEditPanelIsShowVisualization(this.isShowVisualization)
  }

  // @Watch('selectNode')
  // private async onNodeChange() {
  //   this.nodeWidgets = []
  //   if (this.selectNode) {
  //     this.isNodeWidgetsLoading = true
  //     this.nodeWidgets = await this.getWidgets()
  //     this.isNodeWidgetsLoading = false
  //   }
  // }

  @Watch('savingWidgetConfig')
  private onSavingWidgetConfigChange(widgetData: WidgetData) {
    console.log('savingWidgetConfig', widgetData)
    // this.onSave(widgetData)
  }

  private get projectId(): string {
    return (this.$route.params as any).id
  }

  private async onEdit(widget: Widget) {
    DataStore.setVisualWindowShow(true)
    DataStore.setOldItems({
      name: widget.name,
      chartType:
        widget.data.chartType.length > 1
          ? widget.data.chartType[0]
          : <string>widget.data.chartType,
      config: {
        ...widget.data.chartOptions,
        xAxisRenderMode: 'all', // 编辑模式下需要开启all模式（全部参数可控）
        yAxisRenderMode: 'all',
        xAxisGridIsShow: false,
        yAxisGridIsShow: false,
      },
      widgetId: widget.id,
      formData: widget.data.formData,
    })
    this.editingWidget = widget
  }

  private async onConfirmEdit(newWidgetData: WidgetData) {
    merge(newWidgetData.chartOptions, this.miscChartOptions)
    const responseData = await this.updateWidget(
      this.editingWidget!,
      newWidgetData
    )
    DataStore.setVisualWindowShow(false)
    this.editingWidget = null
    this.refreshNodeWidgets(responseData.success, '编辑可视化')
  }

  private async onDelete(widget: Widget) {
    const responseData = await this.deleteWidget(widget)
    this.refreshNodeWidgets(responseData.success, '删除可视化')
  }

  private async onSave(widgetData: WidgetData) {
    const isAlreadySaved = this.nodeWidgets.some((widget) =>
      isEqual(widget.data.formData, widgetData.formData)
    )
    if (isAlreadySaved) {
      this.$message.error('不能重复添加可视化')
      return
    }

    const responseData = await this.saveWidget(widgetData)
    this.refreshNodeWidgets(responseData.success, '添加可视化')
  }

  private async updateWidget(widget: Widget, newWidgetData: any) {
    const response = await updateWidget({
      data: {
        data: newWidgetData,
        id: widget.id,
        name: widget.name,
        tid: this.selectNode.id,
        type: 'task',
        projectId: this.projectId,
      },
    })
    return response.data as ResponseData // {result: widgetId}
  }

  private async deleteWidget(widget: Widget) {
    const response = await deleteWidget({
      data: {
        id: widget.id,
        projectId: localStorage.getItem('projectId'),
        type: 'task',
      },
    })
    return response.data as ResponseData // {result: null}
  }

  // private async refreshNodeWidgets(success: boolean, name?: string) {
  //   if (success) { // TODO
  //     this.nodeWidgets = await this.getWidgets()
  //   }
  //   if (name) {
  //     if (success) {
  //       this.$message.success(`${name}成功`)
  //     } else {
  //       this.$message.error(`${name}失败`)
  //     }
  //   }
  // }

  /**
   * getWidgets ByTaskId
   */
  private async getWidgets(nodeData: any) {
    const response = await widgetQueryByTaskId({
      data: {
        tid: nodeData.tid,
        type: nodeData.type,
      },
    })
    const widgets: Widget[] = response.data?.result ?? []
    const promises = widgets.map(async (widget) => {
      const data = await this.getChartDataByWidget(widget.data)
      widget.data.chartOptions.value = data
      widget.data.chartOptions = {
        ...widget.data.chartOptions,
        ...this.miscChartOptions,
        ...this.getExtraChartOptions(widget.data),
      }
    })
    await Promise.all(promises)
    return widgets
  }

  /**
   * 获取全局可视化收藏列表
   */
  private async getGlobalWidgets(): Promise<void> {
    this.allWidgets = {}
    if (this.pipelineId != null) {
      const response = await getGlobalWidgets({
        data: {
          pageSize: 10,
          taskId: this.selectNode?.id ?? '',
          pipelineId: this.pipelineId,
          projectId: this.projectId,
        },
      })
      this.allWidgets = response.data?.result?.data ?? []

      this.allWidgets.forEach(async (element: { widgets: any }) => {
        const widgets: Widget[] = element?.widgets ?? []
        const promises = widgets.map(async (widget) => {
          const data = await this.getChartDataByWidget(widget.data)
          widget.data.chartOptions.value = data
          widget.data.chartOptions = {
            ...widget.data.chartOptions,
            ...this.miscChartOptions,
            ...this.getExtraChartOptions(widget.data),
          }
        })
        await Promise.all(promises)
      })

      console.log('getGlobalWidgets', this.allWidgets)
      // this.refreshNodeWidgets(response.data.success, '界面初始化')
    }
  }

  private async refreshNodeWidgets(success: boolean, name?: string) {
    if (success) {
      // TODO
      this.allWidgets = []
      this.isNodeWidgetsLoading = true
      this.allWidgets = await this.getGlobalWidgets()
      this.isNodeWidgetsLoading = false
      console.log('待渲染数据', this.allWidgets)
    }
    if (name) {
      if (success) {
        this.$message.success(`${name}成功`)
      } else {
        this.$message.error(`${name}失败`)
      }
    }
  }

  private async getChartDataByWidget(widgetData: WidgetData) {
    const data = await getAndDealWidgetData(widgetData)
    // TODO: temp: remove null entries to avoid rendering error
    return removeNullEntries(<any[]>data)
  }

  private getExtraChartOptions(chart: WidgetData) {
    const result: any = {}
    const { value } = chart.chartOptions

    // hack for 异常检测散点图配色
    if ([1, -1, '1', '-1'].includes(value?.[0]?.label)) {
      const abnormalIndex = value.findIndex((v: any) =>
        [-1, '-1'].includes(v.label)
      )
      if (abnormalIndex > 0) {
        result.value = [
          value[abnormalIndex],
          ...value.slice(0, abnormalIndex),
          ...value.slice(abnormalIndex + 1),
        ]
      }
    }
    // end of hack

    if (
      chart.chartType === 'scatterplot' ||
      chart.chartType[0] === 'scatterplot'
    ) {
      result.size = [200, 200]
      result.pointRadius = 2
    }

    return result
  }

  private async saveWidget(widgetData: WidgetData) {
    const response = await saveWidget({
      data: {
        data: widgetData,
        name: Array.isArray(widgetData.chartType)
          ? widgetData.chartType[0]
          : widgetData.chartType,
        randomId: Math.floor(Math.random() * 10000),
        tid: this.selectNode.id,
        type: 'task',
        projectId: this.projectId,
      },
    })
    return response.data as ResponseData // {result: widgetId}
  }

  private onCancel() {
    DataStore.setVisualWindowShow(false)
  }
}
</script>

<style lang="less" scoped>
.data-visualization-container {
  border-left: 1px solid #d8d8d8;
  height: 100%;
  overflow: hidden;
  width: 360px;

  .section-header {
    align-items: center;
    border-bottom: 1px solid #d8d8d8;
    display: flex;
    height: 38px;
    justify-content: space-between;
    overflow: hidden;
    padding: 0 16px 0 6px;

    .favorite-btn {
      display: flex;
      flex-shrink: 0;

      .icon-btn {
        border-radius: 2px;
        cursor: pointer;
        font-size: 16px;
        margin-right: 6px;
        padding: 0 4px;

        &:hover {
          background-color: #f1f1f1;
        }
      }
    }
  }

  /**收藏内容 */
  .section-content {
    background: #fff;
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow-x: hidden;
    overflow-y: auto;
    width: 100%;

    .list-item {
      flex: 0 0 100px;
      margin: 0 16px;
      min-height: 0;
      position: relative;

      .buttons {
        display: flex;
        flex-direction: row;
        position: absolute;
        right: 30px;
        top: 12px;
        // transform: translateY(-50%);
        // visibility: hidden;
        width: 12px;
        z-index: 300;

        .icon {
          cursor: pointer;
          font-size: 15px;
          margin-right: 10px;

          &:hover {
            color: #6973ff;
          }
        }
      }

      .mask {
        background: transparent;
        cursor: pointer;
        height: 100%;
        left: 0;
        position: absolute;
        top: 0;
        width: calc(100% - 12px);
        z-index: 300;
      }

      &:hover .buttons {
        visibility: visible;
      }

      &:first-of-type {
        margin-top: 10px;
      }

      &:last-of-type {
        margin-bottom: 10px;
      }

      &.more {
        cursor: pointer;
        line-height: 100px;
        text-align: center;
      }

      &.square {
        flex: 0 0 200px;
      }
    }

    .empty-status-container {
      align-items: center;
      display: flex;
      flex-direction: column;
      height: 100%;
      justify-content: center;

      .empty-img {
        margin-bottom: 15px;
      }
    }

    .spinner-mask {
      align-items: center;
      display: flex;
      height: 100%;
      justify-content: center;
      z-index: 1002;
    }

    &::after {
      content: '';
      padding-right: 9px;
    }

    &::-webkit-scrollbar {
      width: 6px;
    }

    &::-webkit-scrollbar-thumb {
      background: rgba(144, 147, 153, 0.5);
      border-radius: 6px;
    }

    &::-webkit-scrollbar-track {
      background: transparent;
      border-radius: 5px;
    }
  }
}
</style>
